package oracle.apps.financials.collection.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import oracle.apps.financials.collection.po.RendererValueHolder;

import org.achartengine.GraphicalView;
import org.achartengine.chart.BarChart;
import org.achartengine.chart.LineChart;
import org.achartengine.chart.PointStyle;
import org.achartengine.chart.TimeChart;
import org.achartengine.chart.XYChart;
import org.achartengine.model.CategorySeries;
import org.achartengine.model.DefaultSeries;
import org.achartengine.model.MultipleCategorySeries;
import org.achartengine.model.TimeSeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.DefaultRenderer;
import org.achartengine.renderer.SimpleSeriesRenderer;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.content.Context;
import android.graphics.Color;

/**
 * An abstract class for the demo charts to extend. It contains some methods for
 * building datasets and renderers.
 */
public class ChartHelper {

	private void ChartHelper() {

	}

	private static void checkParameters(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) {
		if (dataset == null || renderer == null || dataset.getSeriesCount() != renderer.getSeriesRendererCount()) {
			throw new IllegalArgumentException("Dataset and renderer should be not null and should have the same number of series");
		}
	}

	public static final GraphicalView getLineChartView(Context context, XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) {
		checkParameters(dataset, renderer);
		XYChart chart = new LineChart(dataset, renderer);

		return new GraphicalView(context, chart);
	}

	/**
	 * Builds an XY multiple dataset using the provided values.
	 * 
	 * @param titles
	 *            the series titles
	 * @param xValues
	 *            the values for the X axis
	 * @param yValues
	 *            the values for the Y axis
	 * @return the XY multiple dataset
	 */
	public static XYMultipleSeriesDataset buildDataset(String[] titles, List<double[]> xValues, List<double[]> yValues) {
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		addXYSeries(dataset, titles, xValues, yValues, 0);
		return dataset;
	}

	public static XYMultipleSeriesDataset buildDataset(String[] titles, List<double[]> xValues, List<double[]> yValues, int scale) {
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		addXYSeries(dataset, titles, xValues, yValues, scale);
		return dataset;
	}

	public static void addXYSeries(XYMultipleSeriesDataset dataset, String[] titles, List<double[]> xValues, List<double[]> yValues, int scale) {
		int length = titles.length;
		for (int i = 0; i < length; i++) {
			XYSeries series = new XYSeries(titles[i], scale);
			double[] xV = xValues.get(i);
			double[] yV = yValues.get(i);
			int seriesLength = xV.length;
			for (int k = 0; k < seriesLength; k++) {
				series.add(xV[k], yV[k]);
			}
			dataset.addSeries(series);
		}
	}

	/**
	 * Builds an XY multiple series renderer.
	 * 
	 * @param colors
	 *            the series rendering colors
	 * @param styles
	 *            the series point styles
	 * @return the XY multiple series renderers
	 */
	public static XYMultipleSeriesRenderer buildRenderer(int[] colors, PointStyle[] styles) {
		XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
		setRenderer(renderer, colors, styles);
		return renderer;
	}

	public static XYMultipleSeriesRenderer buildRenderer(int[] colors, PointStyle[] styles, int scaleCount) {
		XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer(scaleCount);
		setRenderer(renderer, colors, styles);
		return renderer;
	}

	public static void setRenderer(XYMultipleSeriesRenderer renderer, int[] colors, PointStyle[] styles) {
		renderer.setAxisTitleTextSize(12);
		renderer.setChartTitleTextSize(14);
		renderer.setLabelsTextSize(12);
		renderer.setLegendTextSize(12);
		renderer.setPointSize(5f);
		// top, left, bottom, right
		renderer.setMargins(new int[] { 50, 35, 5, 5 });
		int length = colors.length;
		for (int i = 0; i < length; i++) {
			XYSeriesRenderer r = new XYSeriesRenderer();
			r.setColor(colors[i]);
			r.setPointStyle(styles[i]);
			renderer.addSeriesRenderer(r);
		}
	}

	/**
	 * Sets a few of the series renderer settings.
	 * 
	 * @param renderer
	 *            the renderer to set the properties to
	 * @param title
	 *            the chart title
	 * @param xTitle
	 *            the title for the X axis
	 * @param yTitle
	 *            the title for the Y axis
	 * @param xMin
	 *            the minimum value on the X axis
	 * @param xMax
	 *            the maximum value on the X axis
	 * @param yMin
	 *            the minimum value on the Y axis
	 * @param yMax
	 *            the maximum value on the Y axis
	 * @param axesColor
	 *            the axes color
	 * @param labelsColor
	 *            the labels color
	 */
	public static void setChartSettings(XYMultipleSeriesRenderer renderer, String title, String xTitle, String yTitle, double xMin, double xMax,
			double yMin, double yMax, int axesColor, int labelsColor) {

		setChartSettings(renderer, title, xTitle, yTitle, xMin, xMax, yMin, yMax, axesColor, labelsColor, 0);
	}

	public static void setChartSettings(XYMultipleSeriesRenderer renderer, String title, String xTitle, String yTitle, double xMin, double xMax,
			double yMin, double yMax, int axesColor, int labelsColor, int scale) {
		renderer.setChartTitle(title);
		renderer.setXTitle(xTitle);
		renderer.setYTitle(yTitle);
		renderer.setXAxisMin(xMin, scale);
		renderer.setXAxisMax(xMax, scale);
		renderer.setYAxisMin(yMin, scale);
		renderer.setYAxisMax(yMax, scale);
		renderer.setAxesColor(axesColor);
		renderer.setLabelsColor(labelsColor);
	}

	public static XYMultipleSeriesRenderer getChartSettingsForLineChart(RendererValueHolder rendererValue) {
		XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
		renderer.setAxisTitleTextSize(12);
		renderer.setChartTitleTextSize(12);
		
		renderer.setLabelsTextSize(12);
		renderer.setLegendTextSize(12);
		renderer.setPointSize(2f);

		for (int i = 0; i < rendererValue.getColors().size(); i++) {
			XYSeriesRenderer r = new XYSeriesRenderer();
			r.setColor(rendererValue.getColors().get(i));
			r.setPointStyle(rendererValue.getPointStyles().get(i));
			r.setFillPoints(true);
			r.setLineWidth(2);
			renderer.addSeriesRenderer(r);
		}
		renderer.setContext(rendererValue.getContext());

		renderer.setChartTitle(rendererValue.getChartTitle());

		renderer.setShowChartTitle(rendererValue.isShowChartTitle());

		renderer.setXTitle(rendererValue.getxTitle());
		renderer.setYTitle(rendererValue.getyTitle());
		renderer.setXAxisMin(rendererValue.getxMin());
		renderer.setXAxisMax(rendererValue.getxMax());
		renderer.setYAxisMin(rendererValue.getyMin());
		renderer.setYAxisMax(rendererValue.getyMax());

		
		renderer.setAxesColor(Color.BLACK);
		renderer.setXLabelsColor(Color.BLACK);
		renderer.setYLabelsColor(0, Color.rgb(51, 51, 51));
		renderer.setGridColor(Color.BLACK);

		
		renderer.setApplyBackGroundGradientColor(rendererValue.isApplyBackgroundGradientColor());
		renderer.setFromBackGroundGradientColor(rendererValue.getFromBackgroundGradientColor());
		renderer.setToBackGroundGradientColor(rendererValue.getToBackgroundGradientColor());

		renderer.setyLabelMarginTop(rendererValue.getyLabelMarginTop());
		renderer.setxLegendMarginLeft(rendererValue.getxLegendMarginLeft());

		renderer.setLabelsColor(rendererValue.getLabelsColor());

		renderer.setMarginsColor(Color.rgb(223, 223, 223));
		renderer.setApplyBackgroundColor(true);
		renderer.setBackgroundColor(Color.rgb(223, 223, 223));

		renderer.setMargins(rendererValue.getMargins());

		renderer.setYLabels(6);
		renderer.setXLabels(6);
		renderer.setClickEnabled(true);
		renderer.setSelectableBuffer(100);
		renderer.setLineSliderEnabled(true);
		renderer.setShowLegend(true);
		renderer.setFitLegend(true);
		renderer.setShowXTitle(false);
		renderer.setShowGridX(true);
		renderer.setShowAxes(false);
		return renderer;
	}

	public static XYMultipleSeriesRenderer getChartSettingsForTimeSlider(RendererValueHolder rendererValue) {
		XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();

		renderer.setAxisTitleTextSize(12);
		renderer.setChartTitleTextSize(16);
		renderer.setLabelsTextSize(12);
		renderer.setLegendTextSize(12);
		renderer.setPointSize(5f);
		renderer.setSkipPoints(true);

		for (int i = 0; i < rendererValue.getColors().size(); i++) {
			XYSeriesRenderer r = new XYSeriesRenderer();
			r.setColor(rendererValue.getColors().get(i));
			r.setFillBelowLine(true);
			r.setFillBelowLineColor(Color.rgb(169, 169, 169));
			r.setPointStyle(rendererValue.getPointStyles().get(i));
			renderer.addSeriesRenderer(r);
		}
		renderer.setContext(rendererValue.getContext());
		renderer.setChartTitle(rendererValue.getChartTitle());
		renderer.setXTitle(rendererValue.getxTitle());
		renderer.setYTitle(rendererValue.getyTitle());
		renderer.setXAxisMin(rendererValue.getxMin());
		renderer.setXAxisMax(rendererValue.getxMax());
		renderer.setYAxisMin(rendererValue.getyMin());
		renderer.setYAxisMax(rendererValue.getyMax());

		renderer.setTimeSliderXLeftScale(rendererValue.getTimeSliderXLeftScale());

		renderer.setXLabelsColor(Color.BLACK);
		renderer.setAxesColor(Color.BLACK);
		renderer.setYLabelsColor(0, Color.BLACK);
		renderer.setGridColor(Color.BLACK);

		renderer.setApplyBackGroundGradientColor(rendererValue.isApplyBackgroundGradientColor());
		renderer.setFromBackGroundGradientColor(rendererValue.getFromBackgroundGradientColor());
		renderer.setToBackGroundGradientColor(rendererValue.getToBackgroundGradientColor());

		// renderer.setAxesColor(Color.GRAY);
		// renderer.setLabelsColor(Color.LTGRAY);

		// top, left, bottom, right
		renderer.setMargins(new int[] { 1, 40, 25, 40 });
		if (renderer.getSeriesRendererCount() > 0) {
			((XYSeriesRenderer) renderer.getSeriesRendererAt(0)).setFillBelowLine(true);
			((XYSeriesRenderer) renderer.getSeriesRendererAt(0)).setFillBelowLineColor(Color.argb(150, 50, 50, 50));
			renderer.getSeriesRendererAt(0).setGradientEnabled(true);
		}

		renderer.setXLabels(10);

		renderer.setLineSliderEnabled(false);
		renderer.setmRangeSliderEnabled(true);

		renderer.setMarginsColor(Color.rgb(223, 223, 223));
		renderer.setApplyBackgroundColor(true);
		// renderer.setBackgroundColor(Color.rgb(223, 223, 223));

		renderer.setApplyBackgroundColor(true);
		renderer.setBackgroundColor(Color.argb(80, 50, 50, 50));

		renderer.setShowLabels(false);
		renderer.setShowXLabels(true);
		renderer.setShowLegend(false);

		renderer.setShowGridX(false);
		renderer.setShowAxes(false);
		return renderer;
	}

	/**
	 * Builds an XY multiple time dataset using the provided values.
	 * 
	 * @param titles
	 *            the series titles
	 * @param xValues
	 *            the values for the X axis
	 * @param yValues
	 *            the values for the Y axis
	 * @return the XY multiple time dataset
	 */
	public static XYMultipleSeriesDataset buildDateDataset(String[] titles, List<Date[]> xValues, List<double[]> yValues) {
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		int length = titles.length;
		for (int i = 0; i < length; i++) {
			TimeSeries series = new TimeSeries(titles[i]);
			Date[] xV = xValues.get(i);
			double[] yV = yValues.get(i);
			int seriesLength = yV.length;
			for (int k = 0; k < seriesLength; k++) {
				series.add(xV[k], yV[k]);
			}
			dataset.addSeries(series);
		}
		return dataset;
	}

	public static XYMultipleSeriesDataset buildDateDataset(RendererValueHolder rendererValue) {
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		for (int i = 0; i < rendererValue.getTitles().size(); i++) {
			TimeSeries series = new TimeSeries(rendererValue.getTitles().get(i));
			ArrayList<Date> xV = (ArrayList<Date>) rendererValue.getxValueList().get(i);
			ArrayList<Double> yV = (ArrayList<Double>) rendererValue.getyValueList().get(i);
			if (rendererValue.getSliderTextList() != null) {
				series.setSliderTextX(rendererValue.getSliderTextList().get(2 * i));
				series.setSliderTextY(rendererValue.getSliderTextList().get(2 * i + 1));
			}
			int seriesLength = xV.size();
			for (int k = 0; k < seriesLength && k < yV.size(); k++) {
				series.add(xV.get(k), yV.get(k));
			}
			dataset.addSeries(series);
		}
		return dataset;
	}

	public static CategorySeries buildCategoryDataset(RendererValueHolder rendererValue) {
		CategorySeries series = new CategorySeries(rendererValue.getChartTitle());
		for (int i = 0; i < rendererValue.getDetailValueList().size(); i++) {
			series.add(rendererValue.getTitles().get(i), (Double) rendererValue.getDetailValueList().get(i));
		}
		return series;
	}

	/**
	 * Builds a multiple category series using the provided values.
	 * 
	 * @param titles
	 *            the series titles
	 * @param values
	 *            the values
	 * @return the category series
	 */
	public static MultipleCategorySeries buildMultipleCategoryDataset(String title, List<String[]> titles, List<double[]> values) {
		MultipleCategorySeries series = new MultipleCategorySeries(title);
		int k = 0;
		for (double[] value : values) {
			series.add(2007 + k + "", titles.get(k), value);
			k++;
		}
		return series;
	}

	public static DefaultRenderer getPieCategoryRenderer(RendererValueHolder rendererValue) {
		DefaultRenderer renderer = new DefaultRenderer();
		renderer.setLabelsTextSize(12);
		renderer.setLegendTextSize(12);
		renderer.setChartTitleTextSize(18);
		renderer.setShowChartTitle(true);
		renderer.setStartAngle(210);
		renderer.setLabelsColor(Color.rgb(51, 51, 51));
		renderer.setBackgroundColor(Color.rgb(151, 150, 151));
		renderer.setShowLegend(false);
	
		renderer.setChartTitle(rendererValue.getChartTitle());
		// top, left, bottom, right
		renderer.setMargins(new int[] { 50, 30, 10, 0 });

		for (int i = 0; i < rendererValue.getTitles().size(); i++) {
			SimpleSeriesRenderer r = new SimpleSeriesRenderer();
			r.setGradientEnabled(true);
//			r.setColor(rendererValue.getColors().get(i));
			if (i == 0) {
				r.setGradientStartColor(Color.rgb(33, 139, 228));
				r.setGradientStopColor(Color.rgb(13, 99, 228));
			} else if (i == 1) {
				r.setGradientStartColor(Color.rgb(20, 153, 0));
				r.setGradientStopColor(Color.rgb(55, 171, 1));
			} else if (i == 2) {
				r.setGradientStartColor(Color.rgb(185, 2, 194));
				r.setGradientStopColor(Color.rgb(217, 0, 243));
			} else if (i == 3) {
				r.setGradientStartColor(Color.rgb(206, 178, 0));
				r.setGradientStopColor(Color.rgb(254, 203, 0));
			} else if (i == 4) {
				r.setGradientStartColor(Color.rgb(225, 46, 35));
				r.setGradientStopColor(Color.rgb(233, 92, 32));
			}
			renderer.addSeriesRenderer(r);
		}
		return renderer;
	}

	/**
	 * Builds a bar multiple series dataset using the provided values.
	 * 
	 * @param titles
	 *            the series titles
	 * @param values
	 *            the values
	 * @return the XY multiple bar dataset
	 */
	public static XYMultipleSeriesDataset buildBarDataset(String[] titles, List<double[]> values) {
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		int length = titles.length;
		for (int i = 0; i < length; i++) {
			CategorySeries series = new CategorySeries(titles[i]);
			double[] v = values.get(i);
			int seriesLength = v.length;
			for (int k = 0; k < seriesLength; k++) {
				series.add(v[k]);
			}
			dataset.addSeries(series.toXYSeries());
		}
		return dataset;
	}

	/**
	 * Builds a bar multiple series renderer to use the provided colors.
	 * 
	 * @param colors
	 *            the series renderers colors
	 * @return the bar multiple series renderer
	 */
	public static XYMultipleSeriesRenderer buildBarRenderer(int[] colors) {
		XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
		renderer.setAxisTitleTextSize(16);
		renderer.setChartTitleTextSize(20);
		renderer.setLabelsTextSize(15);
		renderer.setLegendTextSize(15);
		int length = colors.length;
		for (int i = 0; i < length; i++) {
			SimpleSeriesRenderer r = new SimpleSeriesRenderer();
			r.setColor(colors[i]);
			renderer.addSeriesRenderer(r);
		}
		return renderer;
	}

	public static XYMultipleSeriesRenderer getChartSettingsCombinedChart(RendererValueHolder rendererValue) {
		XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer(2);
		renderer.setAxisTitleTextSize(12);
		renderer.setChartTitleTextSize(14);
		renderer.setLabelsTextSize(12);
		renderer.setLegendTextSize(12);
		renderer.setPointSize(5f);

		for (int i = 0; i < rendererValue.getColors().size(); i++) {
			XYSeriesRenderer r = new XYSeriesRenderer();
			r.setColor(rendererValue.getColors().get(i));
			r.setPointStyle(rendererValue.getPointStyles().get(i));
			r.setLineWidth(2);
			if (rendererValue.getTypes().get(i).equals(BarChart.TYPE)) {
				r.setGradientEnabled(true);
				r.setGradientStart(0, Color.rgb(33, 139, 228));
				r.setGradientStop(800, Color.rgb(13, 99, 228));
			}
			renderer.addSeriesRenderer(r);
		}
		renderer.setContext(rendererValue.getContext());
		renderer.setShowChartTitle(rendererValue.isShowChartTitle());
		renderer.setChartTitle(rendererValue.getChartTitle());
		renderer.setXTitle(rendererValue.getxTitle());
		renderer.setYTitle(rendererValue.getyTitle());
		renderer.setXAxisMin(rendererValue.getxMin(), 0);
		renderer.setXAxisMax(rendererValue.getxMax(), 0);
		renderer.setXAxisMin(rendererValue.getxMin(), 1);
		renderer.setXAxisMax(rendererValue.getxMax(), 1);
		renderer.setYAxisMin(rendererValue.getyMinList().get(0).doubleValue(), 0);
		renderer.setYAxisMax(rendererValue.getyMaxList().get(0).doubleValue(), 0);
		renderer.setYAxisMin(rendererValue.getyMinList().get(1).doubleValue(), 1);
		renderer.setYAxisMax(rendererValue.getyMaxList().get(1).doubleValue(), 1);


		renderer.setXLabelsColor(Color.BLACK);
		renderer.setAxesColor(Color.BLACK);
		renderer.setYLabelsColor(0, Color.BLACK);
		renderer.setYLabelsColor(1, Color.BLACK);
		renderer.setGridColor(Color.BLACK);

		renderer.setyLabelMarginTop(rendererValue.getyLabelMarginTop());
		renderer.setxLegendMarginLeft(rendererValue.getxLegendMarginLeft());
		renderer.setMargins(rendererValue.getMargins());

		renderer.setApplyBackGroundGradientColor(rendererValue.isApplyBackgroundGradientColor());
		renderer.setFromBackGroundGradientColor(rendererValue.getFromBackgroundGradientColor());
		renderer.setToBackGroundGradientColor(rendererValue.getToBackgroundGradientColor());
		renderer.setLabelsColor(rendererValue.getLabelsColor());

		renderer.setMarginsColor(Color.rgb(223, 223, 223));
		renderer.setApplyBackgroundColor(true);
		renderer.setBackgroundColor(Color.rgb(223, 223, 223));

		renderer.setMargins(new int[] { 80, 40, 25, 40 });

		renderer.setYLabels(6);
		renderer.setXLabels(6);
		renderer.setClickEnabled(true);
		renderer.setSelectableBuffer(100);
		renderer.setLineSliderEnabled(true);
		renderer.setShowLegend(true);
		renderer.setFitLegend(true);
		renderer.setShowXTitle(false);
		renderer.setShowGridX(true);
		renderer.setShowAxes(false);
		renderer.setBarSpacing(0.2);
		return renderer;
	}

	public static DefaultSeries buildCombinedDateDataset(RendererValueHolder rendererValue) {
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		for (int i = 0; i < rendererValue.getTitles().size(); i++) {
			if ((rendererValue.getTypes().get(i)).equals(BarChart.TYPE)) {
				TimeSeries series = new TimeSeries(rendererValue.getTitles().get(i), 1);
				ArrayList<Date> xV = (ArrayList<Date>) rendererValue.getxValueList().get(i);
				ArrayList<Double> yV = (ArrayList<Double>) rendererValue.getyValueList().get(i);
				if (rendererValue.getSliderTextList() != null) {
					series.setSliderTextX(rendererValue.getSliderTextList().get(2 * i));
					series.setSliderTextY(rendererValue.getSliderTextList().get(2 * i + 1));
				}
				int seriesLength = xV.size();
				for (int k = 0; k < seriesLength; k++) {
					series.add(xV.get(k), yV.get(k));
				}
				dataset.addSeries(series);
			} else if ((rendererValue.getTypes().get(i).equals(TimeChart.TYPE))) {
				TimeSeries series = new TimeSeries(rendererValue.getTitles().get(i));
				ArrayList<Date> xV = (ArrayList<Date>) rendererValue.getxValueList().get(i);
				ArrayList<Double> yV = (ArrayList<Double>) rendererValue.getyValueList().get(i);
				if (rendererValue.getSliderTextList() != null) {
					series.setSliderTextX(rendererValue.getSliderTextList().get(2 * i));
					series.setSliderTextY(rendererValue.getSliderTextList().get(2 * i + 1));
				}
				int seriesLength = xV.size();
				for (int k = 0; k < seriesLength; k++) {
					series.add(xV.get(k), yV.get(k));
				}
				dataset.addSeries(series);
			}
		}
		return dataset;
	}

}
